package com.xjh.basestudy.designmode.structureMode.structureMode2_Composite;

import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author XuJianHua
 * @Date 2022/9/25 0:01
 * @Description 首先，文件夹类继承了抽象节点类Node，并在第3行定义了一个次级节点列表List<Node>，
 * 此处的泛型Node既可以是文件夹又可以是文件，也就是说，文件夹下级可以包含任意多个文件夹或者文件。
 * 然后，代码第5行中的构造方法直接调用父类的构造方法，以初始化其文件夹名。最后，在第10行实现了添加子节点方法add(Node child)，
 * 将传入的子节点添加至次级节点列表List<Node>中。对于“叶”节点文件类，其作为末端节点，不应该具备添加子节点的功能，
 * 1.  public abstract class Node {
 * 2.      protected String name;//节点命名
 * 3.
 * 4.      public Node(String name) {//构造方法需传入节点名
 * 5.          this.name = name;
 * 6.      }
 * 7.
 * 8.      //添加下级子节点方法
 * 9.      protected abstract void add(Node child);
 * 10.
 * 11.     protected void tree(int space){
 * 12.         for (int i = 0; i < space; i++) {
 * 13.             System.out.print("  ");//先循环输出space个空格
 * 14.         }
 * 15.         System.out.println(name);//接着再输出自己的名字
 * 16.     }
 * 17. }
 */
public class Folder extends Node {
    //文件夹可以包含子节点（子文件夹或者文件）
    private List<Node> childrenNodes = new ArrayList<>();

    public Folder(String name) {
        super(name);//调用父类的构造方法
    }

    @Override
    protected void add(Node child) {
        childrenNodes.add(child);//可以添加子节点
    }

    // 文件夹类就比较特殊了，它不仅要先输出自己的名字，还要换行再逐个输出子节点的名字，并且要保证空格逐级递增
    /**
     * 同样，文件夹类也重写并覆盖了父类的tree()方法，并且在第16行调用父类的通用tree()方法输出本文件夹的名字。接下来的逻辑就非常有意思了，
     * 对于下一级的子节点我们需要依次输出，但前提是要把当前的空格数加1，如此一来子节点的位置会往右偏移一格，
     * 这样才能看起来像树形结构一样错落有致。可以看到，在第19行的循环体中我们直接调用了子节点的展示方法并把“加1”后的空格数传递给它即可完成展示。
     * 至于当前文件夹下的子节点到底是“文件夹”还是“文件”，我们完全不必操心，
     * 因为子节点们会使用自己的展示逻辑。如果它们还有下一级子节点，则与此处逻辑相同，继续循环，把逐级递增的空格数传递下去，
     * 直至抵达叶节点为止—始于“文件夹”而终于“文件”，非常完美的递归逻辑。
     * */
    @Override
    protected void tree(int space) {
        super.tree(space);//调用父类通用的tree方法列出自己的名字
        space++;//在循环的子节点前，空格数要加1
        for (Node node : childrenNodes) {
            node.tree(space);//调用子节点的tree方法
        }
// 有数据，但是什么都没有输出是因为没有get方法
        System.out.println("childrenNodes==="+ JSON.toJSONString(childrenNodes));

    }


}

